﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using Gekko.Libraries;
using System.Diagnostics;
using System.IO;
using Ionic.Zip;

namespace Gekko.Forms
{
	public partial class frmVersionUp : Form
	{
		WebClient wc;
		VersionCheck vc;
		delegate void DownloadStartDelegate();

		public frmVersionUp(VersionCheck vc)
		{
			string[] sr;
			string detail = string.Empty;

			InitializeComponent();

			this.vc = vc;
			sr = vc.Comment.Split(new string[] { "\\n" }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string s in sr)
			{
				detail = detail.Insert(detail.Length, s + "\r\n");
			}
			detailBox.AppendText(detail);

			if (wc == null)
			{
				// ダウンロードの準備
				wc = new WebClient();
				wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
				wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
			}
		}

		private void cancelButton_Click(object sender, EventArgs e)
		{
			if (wc != null)
			{
				wc.CancelAsync();
			}

			this.Close();
		}

		private void refButton_Click(object sender, EventArgs e)
		{
			if (downloadFolder.ShowDialog() == DialogResult.OK)
			{
				pathBox.Text = downloadFolder.SelectedPath;
			}
		}

		private void downloadButton_Click(object sender, EventArgs e)
		{
			refButton.Enabled = false;
			downloadButton.Enabled = false;

			DownloadStartDelegate dsd = new DownloadStartDelegate(DownloadStart);
			dsd.Invoke();
		}

		private void DownloadStart()
		{
			if (string.IsNullOrEmpty(pathBox.Text))
			{
				pathBox.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
			}
			wc.DownloadFileAsync(new Uri(vc.Path), Path.Combine(Path.GetTempPath(), "Gekko.zip"));
		}

		private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
		{
			if (e.Error != null)
			{
				MessageBox.Show(string.Format(Properties.Resources.VersionUpError,
					e.Error.GetType().ToString(), e.Error.Message),
					Properties.Resources.SoftwareName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
			}
			else if (e.Cancelled) { }
			else
			{
				using (ZipFile zf = new ZipFile(Path.Combine(Path.GetTempPath(),"Gekko.zip")))
				{
					foreach (ZipEntry z in zf)
					{
						if (z.FileName == "GekkoUpdater.zip")
						{
							z.Extract(Path.GetTempPath(), ExtractExistingFileAction.OverwriteSilently);
							using (ZipFile zfu = new ZipFile(Path.Combine(Path.GetTempPath(), "GekkoUpdater.zip")))
							{
								foreach (ZipEntry ze in zfu)
								{
									ze.Extract(Path.Combine(Path.GetTempPath(), "GekkoUpdater"), ExtractExistingFileAction.OverwriteSilently);
								}
							}
						}
						else
						{
							z.Extract(pathBox.Text, ExtractExistingFileAction.OverwriteSilently);
						}
					}
				}

				if (MessageBox.Show(string.Format(Properties.Resources.VersionUpCompleted, Properties.Resources.SoftwareName),
					Properties.Resources.SoftwareName, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
					== DialogResult.Yes)
				{
					try
					{
						Process.Start(Path.Combine(Path.GetTempPath(), "GekkoUpdater\\GekkoUpdater.exe"),
							"\"" + Path.Combine(pathBox.Text, vc.FileName) + "\" \"" + Application.StartupPath + "\"");
						Program.SystemShutdown = true;
						Application.Exit();
					}
					catch(Exception ex)
					{
						MessageBox.Show(string.Format(Properties.Resources.VersionUpRunException, ex.Message),
							Properties.Resources.SoftwareName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					}
				}
				this.Close();
			}
		}

		private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
		{
			this.Invoke((MethodInvoker)delegate
			{
				downloadProgress.Style = ProgressBarStyle.Continuous;
				downloadProgress.Value = e.ProgressPercentage;
				progressSizeLabel.Text = string.Format("{0} byte(s) / {1} byte(s)", e.BytesReceived, e.TotalBytesToReceive);
			});
		}
	}
}
